/*
* Lokomo OneCMDB - An Open Source Software for Configuration
* Management of Datacenter Resources
*
* Copyright (C) 2006 Lokomo Systems AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via
* paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33
* Danderyd, Sweden.
*
*/
package org.onecmdb.core.internal.storage.hibernate;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.hibernate.tuple.IdentifierProperty;
import org.onecmdb.core.IAttribute;
import org.onecmdb.core.ICi;
import org.onecmdb.core.ICmdbTransaction;
import org.onecmdb.core.IObjectScope;
import org.onecmdb.core.IPath;
import org.onecmdb.core.IRFC;
import org.onecmdb.core.IValue;
import org.onecmdb.core.internal.ccb.AttributeModifiable;
import org.onecmdb.core.internal.ccb.CiModifiable;
import org.onecmdb.core.internal.ccb.CmdbTransaction;
import org.onecmdb.core.internal.ccb.RfcQueryCriteria;
import org.onecmdb.core.internal.ccb.rfc.RFC;
import org.onecmdb.core.internal.model.BasicAttribute;
import org.onecmdb.core.internal.model.ConfigurationItem;
import org.onecmdb.core.internal.model.ItemId;
import org.onecmdb.core.internal.model.Path;
import org.onecmdb.core.internal.model.QueryCriteria;
import org.onecmdb.core.internal.model.QueryResult;
import org.onecmdb.core.internal.storage.IDaoReader;
import org.onecmdb.core.internal.storage.IDaoWriter;
import org.onecmdb.core.internal.storage.expression.OneCMDBExpression;
import org.onecmdb.core.tests.profiler.Profiler;
import org.onecmdb.core.utils.xml.BeanCache;
import org.springframework.dao.ConcurrencyFailureException;
public class HibernateDao implements IDaoReader, IDaoWriter {
private SessionFactory sf;
private String namespace = "oneCMDB";
private volatile boolean sessionLocked;
private Log log = LogFactory.getLog(this.getClass());
private int flushCount = 20;
private TestCache aliasCache = new TestCache();
private TestCache idCache = new TestCache();
public void setSessionFactory(SessionFactory sf) {
this.sf = sf;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getNamespace() {
return (this.namespace);
}
public int getFlushCount() {
return flushCount;
}
public void setFlushCount(int flushCount) {
this.flushCount = flushCount;
}
public void destory() {
log.info("HIBERNATE DAO: Shutdown started");
/*
* No need to do anything here, Spring shutdowns the SessionFactory for
* us... Will be a problem if we are using In Memory HSQL-DB because we
* nee to send SHUTDOWN to it to actually close it!!!! We can't do it
* here because spring has shutdown the sf factory for us!
*/
if (false) {
Session session = getSession();
try {
try {
session.connection().createStatement().execute("SHUTDOWN");
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("Can't create statement 'SHUTDOWN' to DB", e);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("Can't create statement 'SHUTDOWN' to DB", e);
}
} finally {
closeSession(session);
}
} else {
sf.close();
}
log.info("HIBERNATE DAO: Shutdown completed");
}
public void setInterceptor(DaoReaderInterceptor interceptor) {
if (interceptor instanceof DaoReaderInterceptor) {
((DaoReaderInterceptor) interceptor).setDaoReader(this);
}
}
/**
* Retrive a session. There will only exists only ONE open session per
* application. This means that the closeSession() MUST be called once a
* getSession() has been called, else the system will be blocked!
*
* @return
*/
private Session getSession() {
// Lock here
synchronized (sf) {
while (sessionLocked) {
try {
sf.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ConcurrencyFailureException(
"Session wait got interrupted", e);
}
}
// Create Session interceptor...
Session session = sf.openSession();
//sessionLocked = true;
return (session);
}
}
private void closeSession(Session session) {
synchronized (sf) {
try {
session.close();
} finally {
// Relese lock...
//sessionLocked = false;
sf.notifyAll();
}
}
}
private Map<ItemId, ICi> mapdb = new HashMap<ItemId, ICi>();
private Queue<ICmdbTransaction> txqueue = new LinkedList<ICmdbTransaction>();
public Set<ICi> findByTemplate(ICi template) {
return null;
}
public ICi findCiByAlias(IPath<String> path) {
if (path == null) {
return(null);
}
String name = path.getLeaf();
// Test cache..
ICi ci = (ICi) aliasCache.get(name);
if (ci != null) {
return(ci);
}
/*
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("alias", name);
// TODO: Fix this to select better, noe attribute with alias will also be found!
Profiler.start("FindByAlias(" + name + ")");
List list = this.query(ConfigurationItem.class, crit);
Profiler.stop();
*/
/*
Profiler.start("FindByAlias(" + name + ")");
List list = this.hqlQuery("from ConfigurationItem ci where ci.class = ConfigurationItem and ci.alias = '" + name + "'");
Profiler.stop();
*/
/*
Profiler.start("FindByAlias(" + name + ")");
List list = this.hqlQuery("from ConfigurationItem ci where ci.alias = '" + name + "'");
Profiler.stop();
*/
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("alias", name);
List list = query(ConfigurationItem.class, crit);
//List list = this.sqlQuery("select {ci.*} from CI {ci} where alias = '" + name + "'");
if (list.size() == 1) {
ci = (ICi) list.get(0);
aliasCache.put(name, ci);
return(ci);
}
if (list.size() > 1) {
log.error("Ci alias '" + name + "' found more than once " + list.size());
return((ICi)list.get(0));
}
return (null);
}
public IAttribute findAttributeById(ItemId id) {
if (id == null) {
return(null);
}
Session session = getSession();
try {
Object o = null;
IAttribute attribute = (IAttribute) idCache.get(id);
if (attribute != null) {
return(attribute);
}
Profiler.start("findAttributeById(" + id.toString() + ")");
o = session.get(BasicAttribute.class, new Long(((ItemId) id).asLong()));
Profiler.stop();
if (o instanceof IAttribute) {
idCache.put(id, o);
return ((IAttribute) o);
}
return (null);
} finally {
closeSession(session);
}
}
public ICi findById(ItemId id) {
if (id == null) {
return(null);
}
// Check cache, testing, should use hibernates....
ICi ci = (ICi) idCache.get(id);
if (ci != null) {
return(ci);
}
Session session = getSession();
try {
Object o = null;
/*
o = session
.get(BasicAttribute.class, ((ItemId) id).asLong());
if (o instanceof ICi) {
Profiler.stop();
return ((ICi) o);
}
*/
Profiler.start("findICiById(" + id.toString() + ")");
o = session.get(ConfigurationItem.class, ((ItemId) id).asLong());
Profiler.stop();
if (o instanceof ICi) {
idCache.put(id, o);
return ((ICi) o);
}
Profiler.start("findIAttById(" + id.toString() + ")");
o = session.get(BasicAttribute.class, ((ItemId) id).asLong());
Profiler.stop();
if (o instanceof ICi) {
idCache.put(id, o);
return ((ICi) o);
}
return (null);
} finally {
closeSession(session);
}
/*
* ICi ci = mapdb.get(id); if (ci instanceof ConfigurationItem) {
* ((ConfigurationItem)ci).setDaoReader(this); } // TODO: REade from
* database...
*
* return(ci);
*/
}
public List queryHQL(String hql) {
// Quering the db.
Session session = getSession();
try {
Query ciQuery = session.createQuery(hql);
List list = ciQuery.list();
return(list);
} finally {
closeSession(session);
}
}
// Query the db about things.
public List sqlQuery(String sql) {
// Quering the db.
Session session = getSession();
try {
Query query = session.createSQLQuery(sql).addEntity("ci", ConfigurationItem.class);
query.setReadOnly(true);
List list = query.list();
return(list);
} finally {
closeSession(session);
}
}
// Query the db about things.
public List hqlQuery(String hql) {
// Quering the db.
Session session = getSession();
try {
Query query = session.createQuery(hql);
query.setReadOnly(true);
List list = query.list();
return(list);
} finally {
closeSession(session);
}
}
public List query(String entityName, HashMap<String, Object> map) {
// Quering the db.
Session session = getSession();
try {
Profiler.start("query(" + entityName +")");
Criteria criteria = session.createCriteria(entityName);
for (String key : map.keySet()) {
Object value = map.get(key);
if (value == null) {
criteria.add(Expression.isNull(key));
} else {
criteria.add(Expression.eq(key, map.get(key)));
}
}
List objects = criteria.list();
return (objects);
} finally {
Profiler.stop();
closeSession(session);
}
}
public List query(Class clazz, HashMap<String, Object> map) {
StringBuffer profileInfo = null;
if (Profiler.isOn()) {
profileInfo = new StringBuffer();
profileInfo.append("query(");
profileInfo.append(clazz.getSimpleName());
for (String key : map.keySet()) {
profileInfo.append(",");
profileInfo.append(key);
profileInfo.append("=");
profileInfo.append(map.get(key));
}
profileInfo.append(")");
}
// Quering the db.
Session session = getSession();
try {
if (Profiler.isOn()) {
Profiler.start(profileInfo.toString());
}
Criteria criteria = session.createCriteria(clazz);
for (String key : map.keySet()) {
Object value = map.get(key);
if (value == null) {
criteria.add(Expression.isNull(key));
} else {
criteria.add(Expression.eq(key, map.get(key)));
}
}
List objects = criteria.list();
return (objects);
} finally {
Profiler.stop();
closeSession(session);
}
}
public Set<ICi> getAttributeOffsprings(ItemId id) {
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("derivedFromId", id.asLong());
Profiler.start("getAttributeOffspring(" + id + ")");
List list = query(BasicAttribute.class, crit);
Profiler.stop("getAttributeOffspring(" + id + ")");
return (new HashSet<ICi>(list));
}
public Set<ICi> getOffsprings(ItemId id) {
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("derivedFromId", id.asLong());
Profiler.start("getOffspring(" + id + ")");
List list = query(ConfigurationItem.class, crit);
Profiler.stop();
return (new HashSet<ICi>(list));
}
public Set<IAttribute> getAttributesFor(ItemId id) {
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("ownerId", id.asLong());
Profiler.start("getAttributesFor(" + id.toString() + ")");
List list = query(BasicAttribute.class, crit);
Profiler.stop();
return (new HashSet<IAttribute>(list));
}
public ICmdbTransaction findTransaction() {
return (null);
}
public List<IRFC> findRFCForCi(ItemId ciid) {
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("targetId", ciid.asLong());
List list = query(RFC.class, crit);
return (list);
}
public void updateTransaction(ICmdbTransaction tx) {
}
public ICmdbTransaction getTransaction(ItemId id) {
Session session = getSession();
try {
Object o = session.get(CmdbTransaction.class, ((ItemId) id)
.asLong());
if (o instanceof ICmdbTransaction) {
return ((ICmdbTransaction) o);
}
return (null);
} finally {
closeSession(session);
}
}
public List<IRFC> getRfcsForCmdbTx(ItemId id) {
// TODO Auto-generated method stub
return null;
}
private void flushTransaction(ICmdbTransaction cmdbTx) {
Session session = getSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
cmdbTx.setEndTs(new Date());
//storeTx(session, cmdbTx);
session.save(cmdbTx);
tx.commit();
} catch (HibernateException he) {
if (tx != null) {
tx.rollback();
}
throw he;
} finally {
closeSession(session);
}
}
public void rejectTransaction(ICmdbTransaction cmdbTx) {
idCache.clear();
aliasCache.clear();
flushTransaction(cmdbTx);
}
private void storeRFC(Session session, ICmdbTransaction cmdbTx) {
int totalCount = countRFC(cmdbTx.getRfcs());
storeRFCs(session, cmdbTx, cmdbTx.getRfcs(), 0, totalCount);
//session.save(cmdbTx);
}
private int countRFC(List<IRFC> rfcs) {
int count = 0;
for (IRFC rfc : rfcs) {
if (!(
rfc.getClass().equals(CiModifiable.class)
||
rfc.getClass().equals(AttributeModifiable.class)
)) {
count++;
}
if (rfc.getRfcs().size() > 0) {
count += countRFC(rfc.getRfcs());
}
}
return(count);
}
private void storeRFCs(Session session, ICmdbTransaction tx, List<IRFC> rfcs, int count, int totalCount) {
for (IRFC rfc : rfcs) {
// Update tx id.
rfc.setTxId(tx.getId().asLong());
// Don't save Attribute/Ci modifiable.
if (!(
rfc.getClass().equals(CiModifiable.class)
||
rfc.getClass().equals(AttributeModifiable.class)
)) {
count++;
if ((count % flushCount) == 0 ) {
session.flush();
session.clear();
log.info("RFC: flush[" + count + "/" + totalCount + "]");
}
session.save(rfc);
}
if (rfc.getRfcs().size() > 0) {
storeRFCs(session, tx, rfc.getRfcs(), count, totalCount);
}
}
}
public void commitTransaction(IObjectScope scope, ICmdbTransaction cmdbTx) {
idCache.clear();
aliasCache.clear();
Session session = null;
Transaction tx = null;
Profiler.start("commitTx()");
try {
session = getSession();
tx = session.beginTransaction();
int count = 0;
for (ICi item : scope.getDestroyedICis()) {
session.delete(item);
count++;
if ((count % flushCount) == 0 ) {
session.flush();
session.clear();
log.info("DELETE-CI: flush[" + count + "/" + scope.getDestroyedICis().size() + "]");
}
}
count = 0;
for (ICi item : scope.getNewICis()) {
session.save(item);
count++;
if ((count % flushCount) == 0 ) {
session.flush();
session.clear();
log.info("NEW-CI: flush[" + count + "/" + scope.getNewICis().size() + "]");
}
}
count = 0;
for (ICi item : scope.getModifiedICis()) {
session.update(item);
count++;
if ((count % flushCount) == 0 ) {
session.flush();
session.clear();
log.info("UPDATE-CI: flush[" + count + "/" + scope.getModifiedICis().size() + "]");
}
}
cmdbTx.setEndTs(new Date());
storeRFC(session, cmdbTx);// session.update(cmdbTx);
tx.commit();
} catch (HibernateException he) {
if (tx != null) {
tx.rollback();
}
cmdbTx.setRejectCause("Store data to backend failed: " + he.toString());
throw he;
} finally {
closeSession(session);
flushTransaction(cmdbTx);
Profiler.stop("commitTx()");
}
}
/**
* TODO: Need to redo this for performance....
*/
public List<IAttribute> getSourceReference(ICi ci) {
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("valueAsString", ci.getAsString());
crit.put("alias", "source");
List list = query(BasicAttribute.class, crit);
return (list);
}
public List<IAttribute> getTargetReference(ICi ci) {
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("valueAsString", ci.getAsString());
crit.put("alias", "target");
List list = query(BasicAttribute.class, crit);
return (list);
}
public List<IAttribute> getAttributesReferringTo(ICi ci) {
HashMap<String, Object> crit = new HashMap<String, Object>();
crit.put("valueAsString", ci.getAsString());
List list = query(BasicAttribute.class, crit);
return (list);
}
public QueryResult<ICi> query(QueryCriteria criteria, boolean count) {
DetachedCriteria hibCiCriteria = DetachedCriteria.forClass(ConfigurationItem.class);
DetachedCriteria hibAttributeCriteria = DetachedCriteria.forClass(BasicAttribute.class);
// Search in the db...
if (criteria.getOffspringOfId() != null) {
try {
// Query for an unique id.
Long longId = Long.parseLong(criteria.getOffspringOfId());
hibCiCriteria.add(Expression.eq("derivedFromId", longId));
} catch (NumberFormatException e) {
log.warn("QueryCriteria contained not a long offspringId <" + criteria.getCiId());
throw new IllegalArgumentException("Not a correct long ci id <" + criteria.getCiId());
}
} else if (criteria.getOffspringOfAlias() != null) {
ICi ci = findCiByAlias(new Path<String>(criteria.getOffspringOfAlias()));
if (criteria.getOffspringDepth() != null) {
if (ci == null) {
// Is an error, but we don't throw an exception, instead it will return empty/0
DetachedCriteria hibAliasCiCriteria = DetachedCriteria.forClass(ConfigurationItem.class);
hibAliasCiCriteria.add(Expression.eq("alias", criteria.getOffspringOfAlias()));
DetachedCriteria idCriteria = hibAliasCiCriteria.setProjection(Projections.property("longId"));
hibCiCriteria.add(Property.forName("derivedFromId").in(idCriteria));
} else {
// TODO: append %/%/% according to offspring depth.
hibCiCriteria.add(Expression.ilike("templatePath", ci.getTemplatePath() + "/%"));
}
} else {
if (ci != null) {
hibCiCriteria.add(Expression.eq("derivedFromId", ci.getId().asLong()));
} else {
hibCiCriteria.add(Expression.eq("derivedFromId", new Long(0)));
}
}
//hibAttributeCriteria.add(Expression.eq("alias", criteria.getOffspringOfAlias()));
}
if (criteria.getCiAlias() != null) {
hibCiCriteria.add(Expression.eq("alias", criteria.getCiAlias()));
} else if (criteria.getCiId() != null) {
try {
// Query for an unique id.
Long longId = Long.parseLong(criteria.getCiId());
hibCiCriteria.add(Expression.eq("longId", longId));
} catch (NumberFormatException e) {
log.warn("QueryCriteria contained not a long ci id <" + criteria.getCiId());
throw new IllegalArgumentException("Not a correct long ci id <" + criteria.getCiId());
}
/*
if (ci == null || ci instanceof IAttribute) {
if (count) {
result.setTotalHits(0);
}
} else {
if (count) {
result.setTotalHits(1);
}
result.add(ci);
}
return(result);
*/
}
if (criteria.getMatchType() != null) {
ICi type = findCiByAlias(new Path<String>(criteria.getMatchType()));
if (type != null) {
Disjunction orAttribute = Restrictions.disjunction();
String path = type.getTemplatePath();
String paths[] = path.split("/");
if (paths.length > 1) {
for (int i = 1; i < paths.length; i++) {
orAttribute.add(Expression.ilike("typeName", "%#" + paths[i], MatchMode.START));
}
DetachedCriteria typeCrit = DetachedCriteria.forClass(BasicAttribute.class);
typeCrit.add(Expression.isNull("derivedFromId"));
typeCrit.add(orAttribute);
DetachedCriteria idCrit = typeCrit.setProjection(Projections.property("ownerId"));
hibCiCriteria.add(Property.forName("longId").in(idCrit));
if (criteria.getMatchCiPath() != null) {
String idPath = "";
String ciPath[] = criteria.getMatchCiPath().split("/");
if (ciPath.length > 0) {
for (int i = 0; i < ciPath.length; i++) {
ICi ci = findCiByAlias(new Path<String>(ciPath[i]));
if (ci != null) {
idPath += "/" + ci.getId().asLong();
}
}
// TODO: append %/%/% according to offspring depth.
hibCiCriteria.add(Expression.ilike("templatePath", idPath + "/%"));
}
}
}
}
}
if (criteria.isMatchCiTemplates() && criteria.isMatchCiInstances()) {
// Search Both.
} else if (criteria.isMatchCiTemplates()) {
hibCiCriteria.add(Expression.eq("isBlueprint", Boolean.TRUE));
} else if (criteria.isMatchCiInstances()) {
hibCiCriteria.add(Expression.eq("isBlueprint", Boolean.FALSE));
}
if (criteria.isMatchAttributeTemplates() && criteria.isMatchAttributeInstances()) {
// Search both
} else if (criteria.isMatchAttributeTemplates()) {
hibAttributeCriteria.add(Expression.eq("isBlueprint", Boolean.TRUE));
} else if (criteria.isMatchAttributeInstances()) {
hibAttributeCriteria.add(Expression.eq("isBlueprint", Boolean.FALSE));
}
if (criteria.getText() != null) {
Disjunction orAttribute = Restrictions.disjunction();
Disjunction orCi = Restrictions.disjunction();
boolean orAttributeAdded = false;
boolean orCiAdded = false;
if (criteria.isTextMatchAlias()) {
orCi.add(Expression.ilike("alias", criteria.getText(), MatchMode.ANYWHERE));
orAttribute.add(Expression.ilike("alias", criteria.getText(), MatchMode.ANYWHERE));
orAttributeAdded = true;
orCiAdded = true;
}
if (criteria.isTextMatchDescription()) {
orCi.add(Expression.ilike("description", criteria.getText(), MatchMode.ANYWHERE));
orAttribute.add(Expression.ilike("description", criteria.getText(), MatchMode.ANYWHERE));
orAttributeAdded = true;
orCiAdded = true;
}
if (criteria.isTextMatchValue()) {
orAttribute.add(Expression.ilike("valueAsString", criteria.getText(), MatchMode.ANYWHERE));
orAttributeAdded = true;
// Enable Attribute serach....
criteria.setMatchAttribute(true);
}
/*
DetachedCriteria idCriteria = hibAttributeCriteria.setProjection(Projections.property("ownerId"));
orCi.add(Property.forName("longId").in(idCriteria));
*/
if (orAttributeAdded) {
if (criteria.getMatchAttributeAlias() != null) {
hibAttributeCriteria.add(Expression.eq("alias", criteria.getMatchAttributeAlias()));
}
hibAttributeCriteria.add(orAttribute);
DetachedCriteria idCriteria = hibAttributeCriteria.setProjection(Projections.property("ownerId"));
orCi.add(Property.forName("longId").in(idCriteria));
orCiAdded = true;
}
if (orCiAdded) {
hibCiCriteria.add(orCi);
}
}
QueryResult<ICi> result = new QueryResult<ICi>();
/*
if (criteria.isMatchAttribute()) {
DetachedCriteria idCriteria = hibAttributeCriteria.setProjection(Projections.property("ownerId"));
hibCiCriteria.add(Property.forName("longId").in(idCriteria));
}
*/
// Search ICi.
Session session = getSession();
try {
Profiler.start("QueryCi():");
if (count) {
Criteria hibCriteria = hibCiCriteria.getExecutableCriteria(session);
hibCriteria.setProjection(Projections.rowCount());
List list = hibCriteria.list();
if (list != null && !list.isEmpty()) {
Integer itemCount = ((Integer)list.get(0)).intValue();
result.setTotalHits(itemCount);
}
} else {
if (criteria.getOrderAttAlias() != null) {
DetachedCriteria idCriteria = hibCiCriteria.setProjection(Projections.property("longId"));
DetachedCriteria attr = DetachedCriteria.forClass(BasicAttribute.class);
attr.add(Expression.eq("alias", criteria.getOrderAttAlias()));
attr.add(Property.forName("ownerId").in(idCriteria));
if (criteria.isOrderAscending()) {
attr.addOrder(Order.asc(criteria.getOrderType()));
} else {
attr.addOrder(Order.desc(criteria.getOrderType()));
}
Criteria attrCriteria = attr.getExecutableCriteria(session);
if (criteria.getMaxResult() != null) {
attrCriteria.setMaxResults(criteria.getMaxResult());
}
if (criteria.getFirstResult() != null) {
attrCriteria.setFirstResult(criteria.getFirstResult());
}
List<IAttribute> attrs = attrCriteria.list();
for (IAttribute a : attrs) {
result.add(a.getOwner());
}
} else {
hibCiCriteria.addOrder(Order.asc("alias"));
Criteria hibCriteria = hibCiCriteria.getExecutableCriteria(session);
if (criteria.getMaxResult() != null) {
hibCriteria.setMaxResults(criteria.getMaxResult());
}
if (criteria.getFirstResult() != null) {
hibCriteria.setFirstResult(criteria.getFirstResult());
}
List objects = hibCriteria.list();
result.addAll(objects);
}
}
} finally {
Profiler.stop();
closeSession(session);
}
return(result);
}
public Integer queryCriteriaCount(DetachedCriteria detachedCrit) {
Session session = getSession();
List result = Collections.EMPTY_LIST;
Integer itemCount = new Integer(0);
try {
Profiler.start("QueryCriteria():");
Criteria criteria = detachedCrit.getExecutableCriteria(session);
criteria.setProjection(Projections.rowCount());
List list = criteria.list();
if (list != null && !list.isEmpty()) {
itemCount = ((Integer)list.get(0)).intValue();
}
} finally {
Profiler.stop();
closeSession(session);
}
return(itemCount);
}
public List queryCriteria(DetachedCriteria detachedCrit, PageInfo info) {
Session session = getSession();
List result = Collections.EMPTY_LIST;
try {
Profiler.start("QueryCriteria():");
Criteria criteria = detachedCrit.getExecutableCriteria(session);
if (info != null) {
if (info.getFirstResult() != null) {
criteria.setFirstResult(info.getFirstResult());
}
if (info.getMaxResult() != null) {
criteria.setMaxResults(info.getMaxResult());
}
}
result = criteria.list();
} finally {
Profiler.stop();
closeSession(session);
}
return(result);
}
public QueryResult queryExpression(OneCMDBExpression expr) {
QueryResult<ICi> result = new QueryResult<ICi>();
Session session = getSession();
try {
Profiler.start("QueryCi():");
if (expr.isCount()) {
Criteria criteria = expr.composeCriteria().getExecutableCriteria(session);
criteria.setProjection(Projections.rowCount());
List list = criteria.list();
if (list != null && !list.isEmpty()) {
Integer itemCount = ((Integer)list.get(0)).intValue();
result.setTotalHits(itemCount);
}
} else {
// Debug test.
DetachedCriteria aCrit = expr.getOrderCriteria();
if (aCrit != null) {
Criteria criteria = aCrit.getExecutableCriteria(session);
if (expr.getMaxResult() != null) {
criteria.setMaxResults(expr.getMaxResult());
}
if (expr.getFirstResult() != null) {
criteria.setFirstResult(expr.getFirstResult());
}
List objects = criteria.list();
for (Object o : objects) {
result.add(((IAttribute)o).getOwner());
}
} else {
Criteria criteria = expr.composeCriteria().getExecutableCriteria(session);
if (expr.getMaxResult() != null) {
criteria.setMaxResults(expr.getMaxResult());
}
if (expr.getFirstResult() != null) {
criteria.setFirstResult(expr.getFirstResult());
}
List objects = criteria.list();
result.addAll(objects);
}
}
} finally {
Profiler.stop();
closeSession(session);
}
return(result);
}
public QueryResult<ICi> queryOld(QueryCriteria criteria, boolean count) {
DetachedCriteria hibCiCriteria = DetachedCriteria.forClass(ConfigurationItem.class);
DetachedCriteria hibAttributeCriteria = DetachedCriteria.forClass(BasicAttribute.class);
// Search in the db...
if (criteria.getOffspringOfId() != null) {
hibCiCriteria.add(Expression.eq("derivedFromId", criteria.getOffspringOfId()));
hibAttributeCriteria.add(Expression.eq("derivedFromId", criteria.getOffspringOfId()));
}
if (criteria.isMatchCiTemplates() && criteria.isMatchCiInstances()) {
// Search Both.
} else if (criteria.isMatchCiTemplates()) {
hibCiCriteria.add(Expression.eq("isBlueprint", Boolean.TRUE));
} else if (criteria.isMatchCiInstances()) {
hibCiCriteria.add(Expression.eq("isBlueprint", Boolean.FALSE));
}
if (criteria.isMatchAttributeTemplates() && criteria.isMatchAttributeInstances()) {
// Search both
} else if (criteria.isMatchAttributeTemplates()) {
hibAttributeCriteria.add(Expression.eq("isBlueprint", Boolean.TRUE));
} else if (criteria.isMatchAttributeInstances()) {
hibAttributeCriteria.add(Expression.eq("isBlueprint", Boolean.FALSE));
}
if (criteria.getText() != null) {
Disjunction orAttribute = Restrictions.disjunction();
Disjunction orCi = Restrictions.disjunction();
boolean orAttributeAdded = false;
boolean orCiAdded = false;
if (criteria.isTextMatchAlias()) {
orCi.add(Expression.ilike("alias", criteria.getText(), MatchMode.ANYWHERE));
orAttribute.add(Expression.ilike("alias", criteria.getText(), MatchMode.ANYWHERE));
orAttributeAdded = true;
orCiAdded = true;
}
if (criteria.isTextMatchDescription()) {
orCi.add(Expression.ilike("description", criteria.getText(), MatchMode.ANYWHERE));
orAttribute.add(Expression.ilike("description", criteria.getText(), MatchMode.ANYWHERE));
orAttributeAdded = true;
orCiAdded = true;
}
if (criteria.isTextMatchValue()) {
orAttribute.add(Expression.ilike("valueAsString", criteria.getText(), MatchMode.ANYWHERE));
orAttributeAdded = true;
}
if (orAttributeAdded) {
hibAttributeCriteria.add(orAttribute);
}
if (orCiAdded) {
hibCiCriteria.add(orCi);
}
}
QueryResult<ICi> result = new QueryResult<ICi>();
if (criteria.isMatchCi()) {
// Search ICi.
Session session = getSession();
// Lock taken, can not do anything else.
try {
Profiler.start("QueryCi():");
Criteria hibCriteria = hibCiCriteria.getExecutableCriteria(session);
if (count) {
hibCriteria.setProjection(Projections.rowCount());
List list = hibCriteria.list();
if (list != null && !list.isEmpty()) {
Integer itemCount = ((Integer)list.get(0)).intValue();
result.setTotalHits(itemCount);
}
} else {
if (criteria.getMaxResult() != null) {
hibCriteria.setMaxResults(criteria.getMaxResult());
}
if (criteria.getFirstResult() != null) {
hibCriteria.setFirstResult(criteria.getFirstResult());
}
hibCriteria.addOrder(Order.asc("alias"));
List objects = hibCriteria.list();
result.addAll(objects);
}
} finally {
Profiler.stop();
closeSession(session);
}
}
if (criteria.isMatchAttribute()) {
// Serach Attributes.
List<ICi> cis = null;
Session session = getSession();
// Lock taken, can not do anything else.
try {
Profiler.start("QueryAttribute():");
DetachedCriteria idCriteria = hibAttributeCriteria.setProjection(Projections.property("ownerId"));
DetachedCriteria crit = DetachedCriteria.forClass(ConfigurationItem.class);
crit.add(Property.forName("longId").in(idCriteria));
Criteria hibCriteria = crit.getExecutableCriteria(session);
if (count) {
hibCriteria.setProjection(Projections.rowCount());
List list = hibCriteria.list();
if (list != null && !list.isEmpty()) {
Integer itemCount = ((Integer)list.get(0)).intValue();
result.setTotalHits(result.getTotalHits() + itemCount);
}
} else {
if (criteria.getMaxResult() != null) {
hibCriteria.setMaxResults(criteria.getMaxResult());
}
if (criteria.getFirstResult() != null) {
hibCriteria.setFirstResult(criteria.getFirstResult());
}
hibCriteria.addOrder(Order.asc("alias"));
cis = hibCriteria.list();
}
} finally {
Profiler.stop();
closeSession(session);
}
if (!count) {
if (cis != null) {
for (ICi ci : cis) {
if (ci.isBlueprint()) {
if (!criteria.isMatchCiTemplates()) {
continue;
}
} else {
if (!criteria.isMatchCiInstances()) {
continue;
}
}
if (!result.contains(ci)) {
result.add(ci);
}
}
}
}
}
return(result);
}
/**
* Query RFC's history for a CI.
* The Ci param can bu NULL meaning all changes will be
* asked for.
*/
public QueryResult<IRFC> queryRfc(ICi ci, RfcQueryCriteria crit, boolean count) {
Collection<IAttribute> attributes = null;
if (crit.isFetchAttributes()) {
if (ci != null) {
if (crit.getAttributeAlias() != null) {
attributes = ci.getAttributesWithAlias(crit.getAttributeAlias());
} else {
attributes = ci.getAttributes();
}
}
}
QueryResult<IRFC> result = new QueryResult<IRFC>();
// Quering the db.
Session session = getSession();
// Lock taken, can not do anything else.
try {
Profiler.start("QueryRfc():");
Criteria criteria = session.createCriteria(crit.getRfcClass());
if (ci != null) {
if (crit.isFetchAttributes()) {
Disjunction or = Restrictions.disjunction();
or.add(Expression.eq("targetId", ci.getId().asLong()));
for (IAttribute a : attributes) {
or.add(Expression.eq("targetId", a.getId().asLong()));
}
criteria.add(or);
} else {
criteria.add(Expression.eq("targetId", ci.getId().asLong()));
}
}
if (crit.getTxId() != null) {
criteria.add(Expression.eq("txId", crit.getTxId()));
}
if (crit.getFromDate() != null && crit.getToDate() != null) {
criteria.add(Expression.between("ts", crit.getFromDate(), crit.getToDate()));
} else if (crit.getFromDate() != null) {
// Search to date.
criteria.add(Expression.ge("ts", crit.getFromDate()));
} else if (crit.getToDate() != null) {
// Serach from date.
criteria.add(Expression.le("ts", crit.getToDate()));
} else {
// No criteria on date.
}
if (count) {
criteria.setProjection(Projections.rowCount());
List list = criteria.list();
if (list != null && !list.isEmpty()) {
Integer itemCount = ((Integer)list.get(0)).intValue();
result.setTotalHits(itemCount);
}
} else {
if (crit.getMaxResult() != null) {
criteria.setMaxResults(crit.getMaxResult());
}
if (crit.getFirstResult() != null) {
criteria.setFirstResult(crit.getFirstResult());
}
if (crit.isDescendingOrder()) {
criteria.addOrder( Order.desc("ts") );
} else {
criteria.addOrder( Order.asc("ts") );
}
List objects = criteria.list();
result.addAll(objects);
}
} finally {
Profiler.stop();
closeSession(session);
}
return(result);
}
public void storeTransaction(ICmdbTransaction cmdbTx) {
Session session = getSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
storeRFC(session, cmdbTx);
tx.commit();
} catch (HibernateException he) {
if (tx != null) {
tx.rollback();
}
throw he;
} finally {
closeSession(session);
flushTransaction(cmdbTx);
}
}
}